import requests
import json
import logging
from datetime import datetime
import time
import random
from typing import Dict, Any
from .helpers import ComHelper

# 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

class SmsService:
    """
    短信服务类，负责调用第三方短信接口
    """
    
    # 错误码映射字典，将第三方API错误码映射为更友好的错误描述
    ERROR_CODES = {
        '21': '短信发送失败，请检查手机号格式',
        '01': '参数错误，请检查请求参数',
        '02': '签名验证失败，请检查AppKey配置',
        '03': '用户不存在或账号状态异常',
        '04': '余额不足，请检查账户余额',
        '05': '请求频率过高，请稍后重试',
        '06': '模板不存在或已禁用',
        '07': '手机号在黑名单中',
        '99': '系统繁忙，请稍后重试',
        'error': '网络请求失败，请检查网络连接'
    }
    
    def __init__(self, api_url: str, mch_id: str, app_id: str, template_id: str, app_key: str):
        """
        初始化短信服务
        
        Args:
            api_url: 第三方短信接口URL
            mch_id: 商户ID
            app_id: 应用ID
            template_id: 短信模板ID
            app_key: 应用密钥
        """
        self.api_url = api_url
        self.mch_id = mch_id
        self.app_id = app_id
        self.template_id = template_id
        self.app_key = app_key
    
    def generate_verification_code(self) -> str:
        """
        生成6位数字验证码
        
        Returns:
            验证码字符串
        """
        return str(random.randint(100000, 999999))
    
    def get_timestamp(self) -> int:
        """
        获取当前时间戳（毫秒）
        
        Returns:
            时间戳
        """
        return int(time.time() * 1000)
    
    def validate_phone_number(self, phone_number: str) -> bool:
        """
        验证手机号格式是否正确
        
        Args:
            phone_number: 手机号码
            
        Returns:
            bool: 手机号格式是否正确
        """
        # 简单的中国大陆手机号格式验证
        import re
        pattern = r'^1[3-9]\d{9}$'
        return bool(re.match(pattern, phone_number))
    
    def send_sms(self, phone_number: str, verification_code: str) -> Dict[str, Any]:
        """
        发送短信
        
        Args:
            phone_number: 手机号码
            verification_code: 验证码
            
        Returns:
            响应结果字典，包含status、message和可能的taskId
        """
        # 先验证手机号格式
 
        # 构建请求参数
        payload = {
            'MchId': self.mch_id,
            'AppId': self.app_id,
            'Version': '1.2.0',
            'PhoneNumberSet': [phone_number],
            'SignType': 'MD5',
            'TemplateId': self.template_id,
            'TimeStamp': self.get_timestamp(),
            'TemplateParamSet': [verification_code]
        }
        
        # 生成签名
        payload['Signature'] = ComHelper.get_signature(payload, self.app_key)
        
        logger.info(f"准备发送短信到 {phone_number}，验证码: {verification_code}")
        
        try:
            # 发送请求
            response = requests.post(
                self.api_url,
                headers={'Content-Type': 'application/json'},
                data=json.dumps(payload),
                timeout=30  # 添加超时设置
            )
            
            # 检查响应状态码
            response.raise_for_status()
            
            # 解析响应
            result = response.json()
            logger.info(f"短信发送响应: {result}")
            
            # 如果返回了错误码，使用映射字典提供更友好的错误描述
            status = result.get('status')
            if status != '00' and status in self.ERROR_CODES:
                result['message'] = self.ERROR_CODES[status]
            
            return result
            
        except requests.exceptions.Timeout:
            logger.error("短信发送请求超时")
            return {
                'status': 'error',
                'message': '短信发送超时，请稍后重试'
            }
        except requests.exceptions.ConnectionError:
            logger.error("短信发送连接错误")
            return {
                'status': 'error',
                'message': '短信服务连接失败，请检查网络连接'
            }
        except requests.exceptions.RequestException as e:
            logger.error(f"短信发送请求异常: {str(e)}")
            return {
                'status': 'error',
                'message': f'短信发送请求异常: {str(e)}'
            }
        except json.JSONDecodeError:
            logger.error("短信发送响应解析失败")
            return {
                'status': 'error',
                'message': '短信服务响应格式错误'
            }
        except Exception as e:
            logger.error(f"短信发送未知错误: {str(e)}")
            return {
                'status': 'error',
                'message': f'短信发送失败: {str(e)}'
            }